import axios, { AxiosError } from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import qs from 'qs'
import { config } from '@/config/axios/config'
import errorCode from './errorCode'

import { resetRouter } from '@/router'
import { deleteUserCache } from '@/hooks/web/useCache'
import { el } from 'element-plus/es/locale'
const { base_url, result_code, request_timeout } = config

// 需要忽略的提示。忽略后，自动 Promise.reject('error')
const ignoreMsgs = [
  '无效的刷新令牌', // 刷新令牌被删除时，不用提示
  '刷新令牌已过期' // 使用刷新令牌，刷新获取新的访问令牌时，结果因为过期失败，此时需要忽略。否则，会导致继续 401，无法跳转到登出界面
]
// 需要忽略的提示。忽略后，自动 Promise.reject('error')
// 是否显示重新登录
export const isRelogin = { show: false }

let requestList: any[] = []
let isRefreshToken = false
const whiteList = ['/login', '/refreshToken']
const service: AxiosInstance = axios.create({
  baseURL: base_url,
  timeout: request_timeout,
  withCredentials: false,
  paramsSerializer: {
    serialize: (params: Record<string, any>) => qs.stringify(params, { allowDots: true })
  }

})
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 统一添加token
    let isToken = (config.headers || {}).isToken === false
    whiteList.some((v) => {
      if (config.url && config.url.indexOf(v) > -1) {
        return (isToken = false)
      }
    })
    const method = config.method?.toUpperCase()    // 开启loading
    // addLoadingRequest(config)
    if (method === 'GET') {
      config.headers['Cache-Control'] = 'no-cache'
      config.headers['Pragma'] = 'no-cache'
    }
    else if (method === 'POST') {
      const contentType = config.headers['Content-Type'] || config.headers['content-type']
      if (contentType == 'application/x-www-form-urlencoded') {
        if (config.data && typeof config.data !== 'string') {
          config.data = qs.stringify(config.data)
        }
      }
    }
    return config
  },
  (error: AxiosError) => {
    console.log(error)
    return Promise.reject(error)
  }

)
service.interceptors.response.use(
  async (response: AxiosResponse<any>) => {
    let { data } = response
    const config = response.config
    if (!data) {
      throw new Error()
    }
    const { t } = useI18n()
    if (response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') {
      if (response.data.type !== 'application/json') {
        return response.data
      }
      data = await new Response(response.data).json()
    }
    const code = data.code || result_code
    const msg = data.msg || errorCode[code] || errorCode['default']
    if (ignoreMsgs.indexOf(msg) !== -1) {
      return Promise.reject(msg)
    }
    else if (code === 401) {

    }
    else if (code === 500) {
      ElMessage.error(t('sys.api.errorMsg500'))
      return Promise.reject(new Error(msg))
    }
    else if (code === 901) {
      ElNotification.error({
        title: msg
      })
      return Promise.reject('error')
    }
    else if (code !== 200) {
      ElNotification.error({
        title: msg
      })
      return Promise.reject('error')
    }
    else {
      return data
    }

  },
  (error: AxiosError) => {
    console.log('err' + error)
    let { message } = error
    const { t } = useI18n()
    if (message === 'Network Error') {
      message = t('sys.api.errorMessage')
    } else if (message.includes('timeout')) {
      message = t('sys.api.apiTimeoutMessage')
    } else if (message.includes('Request failed with status code')) {
      message = t('sys.api.apiRequestFailed') + message.substr(message.length - 3)
    }
    ElMessage.error(message)
    return Promise.reject(error)
  }

)
export { service }